import tkinter as tk
from tkinter import simpledialog, messagebox
import random
from pypinyin import pinyin, Style

# 用户类
class User:
    def __init__(self, username):
        self.username = username
        self.score = 0
        self.hint_count = 2  # 每个用户初始有2次提示机会

    def add_score(self, points):
        self.score += points

    def use_hint(self):
        if self.hint_count > 0:
            self.hint_count -= 1
            return True
        else:
            return False

    def __str__(self):
        return f"用户：{self.username}，得分：{self.score}，剩余提示次数：{self.hint_count}"

# 读取成语大全数据库
def load_idioms(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            idioms = file.readlines()
        return [idiom.strip() for idiom in idioms]
    except FileNotFoundError:
        print(f"文件未找到：{file_path}")
        return []
    except Exception as e:
        print(f"加载成语库时出错：{e}")
        return []

# 获取随机成语
def get_random_idiom(idioms):
    return random.choice(idioms)

# 判断成语是否在数据库中
def is_idiom_in_database(idiom, idioms):
    return idiom in idioms

# 获取机器接龙的成语
def get_machine_idiom(last_idiom, idioms):
    last_char_pinyin = pinyin(last_idiom[-1], style=Style.NORMAL)[0][0]
    available_idioms = [idiom for idiom in idioms if pinyin(idiom[0], style=Style.NORMAL)[0][0] == last_char_pinyin]

    if available_idioms:
        return random.choice(available_idioms)
    else:
        return None

# 获取提示
def get_hint(last_idiom, idioms):
    last_char_pinyin = pinyin(last_idiom[-1], style=Style.NORMAL)[0][0]
    hints = [idiom for idiom in idioms if pinyin(idiom[0], style=Style.NORMAL)[0][0] == last_char_pinyin]

    if hints:
        return random.choice(hints)
    else:
        return None

# 游戏主界面
class GameApp:
    def __init__(self, root, idioms, users, time_limit=10, mode='human_vs_machine'):
        self.root = root
        self.idioms = idioms
        self.users = users
        self.time_limit = time_limit
        self.mode = mode
        self.current_idiom = get_random_idiom(idioms)
        self.current_user_index = 0
        self.current_user = self.users[self.current_user_index]

        self.root.title("成语接龙游戏")
        self.root.geometry("600x400")

        self.label_current_idiom = tk.Label(root, text=f"当前成语：{self.current_idiom}", font=("Arial", 16))
        self.label_current_idiom.pack(pady=20)

        self.label_time = tk.Label(root, text=f"剩余时间：{time_limit}秒", font=("Arial", 16))
        self.label_time.pack(pady=10)

        self.label_user = tk.Label(root, text=f"当前用户：{self.current_user.username}", font=("Arial", 16))
        self.label_user.pack(pady=10)

        self.entry_user_input = tk.Entry(root, font=("Arial", 14), width=30)
        self.entry_user_input.pack(pady=10)
        self.entry_user_input.focus()

        self.button_submit = tk.Button(root, text="提交", command=self.submit_idiom, font=("Arial", 14))
        self.button_submit.pack(pady=10)

        if self.mode == 'human_vs_machine':
            self.button_hint = tk.Button(root, text="提示", command=self.give_hint, font=("Arial", 14))
            self.button_hint.pack(pady=10)

        self.label_status = tk.Label(root, text="", font=("Arial", 14))
        self.label_status.pack(pady=20)

        self.start_countdown()

    def start_countdown(self):
        self.remaining_time = self.time_limit
        self.update_countdown()

    def update_countdown(self):
        self.label_time.config(text=f"剩余时间：{self.remaining_time}秒")
        if self.remaining_time > 0:
            self.remaining_time -= 1
            self.root.after(1000, self.update_countdown)
        else:
            self.time_up()

    def time_up(self):
        self.label_status.config(text="时间到！未在规定时间内完成接龙，机器自动接龙。")
        self.current_user.add_score(-10)  # 超时扣分
        machine_idiom = get_machine_idiom(self.current_idiom, self.idioms)
        if machine_idiom:
            self.label_current_idiom.config(text=f"机器接龙成语：{machine_idiom}")
            self.current_idiom = machine_idiom
        else:
            self.label_status.config(text="机器无法接龙，游戏结束！")
            self.end_game()

        self.next_user()

    def submit_idiom(self):
        user_input = self.entry_user_input.get().strip()
        if not user_input:
            self.label_status.config(text="请输入一个成语！")
            return

        last_char_pinyin = pinyin(self.current_idiom[-1], style=Style.NORMAL)[0][0]
        user_first_char_pinyin = pinyin(user_input[0], style=Style.NORMAL)[0][0]

        if user_first_char_pinyin != last_char_pinyin:
            self.label_status.config(text=f"成语接龙错误，应以'{self.current_idiom[-1]}'的拼音开头。")
            self.current_user.add_score(-10)  # 接龙错误扣分
        elif not is_idiom_in_database(user_input, self.idioms):
            self.label_status.config(text="输入的成语不在数据库中。")
        else:
            self.label_status.config(text=f"用户给出成语：{user_input}")
            self.current_user.add_score(20)  # 接龙成功加分
            self.current_idiom = user_input
            self.label_current_idiom.config(text=f"当前成语：{self.current_idiom}")

            if self.mode == 'human_vs_machine':
                machine_idiom = get_machine_idiom(self.current_idiom, self.idioms)
                if machine_idiom:
                    self.label_current_idiom.config(text=f"机器接龙成语：{machine_idiom}")
                    self.current_idiom = machine_idiom
                else:
                    self.label_status.config(text="机器无法接龙，游戏结束！")
                    self.end_game()

        self.entry_user_input.delete(0, tk.END)
        self.next_user()

    def give_hint(self):
        if self.current_user.use_hint():
            hint = get_hint(self.current_idiom, self.idioms)
            if hint:
                self.label_status.config(text=f"提示：{hint}")
            else:
                self.label_status.config(text="没有更多提示了，请继续尝试。")
            self.current_user.add_score(-5)  # 使用提示扣分
        else:
            self.label_status.config(text="您的提示次数已用完，请继续尝试。")

    def next_user(self):
        self.current_user_index = (self.current_user_index + 1) % len(self.users)
        self.current_user = self.users[self.current_user_index]
        self.label_user.config(text=f"当前用户：{self.current_user.username}")
        self.start_countdown()

    def end_game(self):
        scores = "\n".join(str(user) for user in self.users)
        messagebox.showinfo("游戏结束", f"游戏结束！\n{scores}")
        self.root.destroy()

# 模式选择界面
def select_mode(root, idioms):
    def start_game(mode):
        if mode == 'human_vs_machine':
            username = simpledialog.askstring("输入", "请输入您的用户名:", parent=root)
            if username is None:
                return
            users = [User(username)]
            app = GameApp(root, idioms, users, mode='human_vs_machine')
        else:
            num_users = simpledialog.askinteger("输入", "请输入玩家数量:", parent=root, minvalue=2)
            if num_users is None:
                return
            users = []
            for i in range(num_users):
                username = simpledialog.askstring("输入", f"请输入玩家{i+1}的用户名:", parent=root)
                if username is None:
                    return
                users.append(User(username))
            app = GameApp(root, idioms, users, mode='multi_player')
        root.deiconify()  # 显示主窗口

    root.withdraw()  # 隐藏主窗口
    mode_window = tk.Toplevel(root)
    mode_window.title("选择游戏模式")
    mode_window.geometry("300x200")

    label = tk.Label(mode_window, text="请选择游戏模式:", font=("Arial", 14))
    label.pack(pady=20)

    button_human_vs_machine = tk.Button(mode_window, text="人机对战", command=lambda: start_game('human_vs_machine'), font=("Arial", 14))
    button_human_vs_machine.pack(pady=10)

    button_multi_player = tk.Button(mode_window, text="多人模式", command=lambda: start_game('multi_player'), font=("Arial", 14))
    button_multi_player.pack(pady=10)

# 主函数
if __name__ == "__main__":
    try:
        file_path = 'E:/成语大全.txt'
        idioms = load_idioms(file_path)
        if not idioms:
            print("成语库为空，无法开始游戏。")
            exit(1)

        root = tk.Tk()
        select_mode(root, idioms)
        root.mainloop()
    except Exception as e:
        print(f"程序运行时出错：{e}")